
/**
 * @class Kohive.app.CommentsController
 * @extends ExtMVC.Controller
 * Manages the finding and creation of comments.
 * This is different to most controllers because many of the methods take a reference to
 * another model - the model to attach the comment to
 */
Kohive.app.CommentsController = Ext.extend(ExtMVC.Controller, {
			constructor		: function() {
				Kohive.app.CommentsController.superclass.constructor.call(this,
						{
							viewsPackage	: Kohive.views.comments
						}
				);

				this.initEvents();
				this.initListeners();
			},

			/**
			 * @action load
			 * Attempts to load the comments for the supplied model instance
			 * @param {ExtMVC.Model.Base} model The model to load comments for
			 */
			load			: function(model) {
				Kohive.models.Comment.findAll({
							url			: this.urlForModel(model),
							scope		: this,
							listeners	: {
								scope	: this,
								load	: function(comments) {
									this.fireEvent('load', comments, model);
								}
							}
						});
			},

			/**
			 * @action create
			 * Attempts to create a new comment
			 * @param {ExtMVC.Model.Base} model The model to attach the new comment to
			 * @param {String} commentText The text of the comment to create
			 */
			create			: function(model, commentText) {
				var comment = new Kohive.models.Comment({
							content	: commentText
						});

				this.fireEvent('before-create', comment, model);

				comment.save({
							url		: this.urlForModel(model),
							scope	: this,
							success	: function(record, response) {
								// create the comment from the response
								var comment = new Kohive.models.Comment(Ext
										.decode(response.responseText));

								this.fireEvent('create', comment, model);
							},
							failure	: function() {
								this.fireEvent('create-failed', comment, model);
							}
						}
				);
			},

			/**
			 * @action update
			 * Attempts to update an existing comment
			 * @param {Kohive.models.Comment} comment The comment to update
			 * @param {Object} fields A key : value object of fields to update on this comment
			 */
			update			: function(comment, fields) {
				for (var key in fields) {
					comment.set(key, fields[key]);
				}

				comment.save({
							url		: this.commentUrl(comment),
							scope	: this,
							success	: function() {
								this.fireEvent('update', comment);
							}
						});
			},

			/**
			 * @action destroy
			 * Attempts to destroy an existing comment
			 * @param {Kohive.models.Comment} comment The comment to destroy
			 */
			destroy			: function(comment) {
				comment.destroy({
							url		: this.commentUrl(comment),
							scope	: this,
							success	: function() {
								this.fireEvent('destroy', comment);
							},
							failure	: function() {
								this.fireEvent('destroy-failure', comment);
							}
						});
			},

			/**
			 * Generates a url to retrieve comments from for a given model instance.
			 * This really ought to be done at the model layer :/
			 * @param {ExtMVC.Model.Base|Null} model The model to generate the comments url for, or null for Comments index
			 * @return {String} The url for comments on the given model
			 */
			urlForModel		: function(model) {
				if (typeof model == 'undefined') {
					return this.scopedUrl("/comments");
				} else {
					var refId = model.get('id'), refType = model.modelName;

					return this.scopedUrl(String.format(
							"/comments?reference_id={0}&reference_type={1}",
							refId, refType
					));
				}
			},

			/**
			 * Returns the scoped url for a given comment instance
			 * @param {Kohive.models.Comment} comment The comment to retrieve a url for
			 * @return {String} The comment's scoped url
			 */
			commentUrl		: function(comment) {
				return this.scopedUrl(String.format("/comments/{0}", comment
								.get('id')));
			},

			/**
			 * Scopes a given url to the current membership
			 * @param {String} url The url fragment to scope to the current membership
			 * @return {String} The scoped url
			 */
			scopedUrl		: function(url) {
				var memId = Kohive.OS.getCurrentHive().get('id');

				return String.format("/memberships/{0}{1}", memId, url);
			},

			/**
			 * Sets up all of the events emitted by this controller
			 */
			initEvents		: function() {
				this.addEvents(
						/**
				 * @event load
				 * Fires when comments for a particular model have been loaded
				 * @param {Ext.data.Store} comments An Ext.data.Store containing the comments for this model
				 * @param {ExtMVC.Model.Base} model The model instance that comments were found for
				 */
						'load',

						/**
						 * @event before-create
						 * Fires when a new comment is going to be created
						* @param {Kohive.models.Comment} comment The comment about to be created
						* @param {ExtMVC.Model.Base} model The model the comment was created on
						 */
						'before-create',

						/**
						 * @event create
						 * Fires when a new comment has been successfully created
						 * @param {Kohive.models.Comment} comment The newly created comment
						 * @param {ExtMVC.Model.Base} model The model the comment was created on
						 */
						'create',

						/**
						 * @event update
						 * Fires when a comment has been successfully updated
						 * @param {Kohive.models.Comment} comment The newly updated comment
						 */
						'update',

						/**
						 * @event destroy
						 * Fires when a comment has been successfully destroyed
						 * @param {Kohive.models.Comment} comment The comment that was destroyed
						 */
						'destroy'
				);
			},

			/**
			 * Sets up listeners on other controllers
			 */
			initListeners	: function() {
				Kohive.OS.getController('photos').on({
							scope			: this,
							'show-image'	: this.load
						});
			}
		}
);

Kohive.OS.registerController('comments', Kohive.app.CommentsController);